package org.dyndns.opendemogroup.optimizer.selections;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Random;

import org.dyndns.opendemogroup.optimizer.IOptimizationProblem;
import org.dyndns.opendemogroup.optimizer.Member;
import org.dyndns.opendemogroup.optimizer.problems.OneMax;
import org.junit.Test;

/**
 * A class to test the class Tournament
 */
public class TournamentTest
{

	/**
	 * Tests the <i>fight</i> method with a typical simulation.
	 */
	@Test
	public void fight_TypicalSimulation ( )
	{
		// { initialization
		Random randomSource = new Random ( 42 );
		final int memberSize = 100;
		IOptimizationProblem problem = new OneMax ( memberSize );
		int[] distribution =
		{
			8, 17, 25, 50
		};
		Member[] participants = new Member[distribution.length];
		for ( int i = 0; i < distribution.length; i++ )
		{
			participants[i] = new Member ( memberSize );
			RouletteWheelTest.populateMemberForFitness ( distribution[i],
				participants[i] );
			participants[i].decode ( problem, null );
		}
		Arrays.sort ( participants, null );
		// }

		// { run the tests
		double fairnessProbability = 0.5;
		int tournamentSize = distribution.length;
		// notice how the fittest is expected to win half of the trials??
		int[] expectedWinners = new int[]
		{
			0, 3, 2, 2, 3, 3, 0, 2, 3, 3, 1, 3
		};
		for ( int i = 0; i < expectedWinners.length; i++ )
		{
			Member actual =
				Tournament.fight ( randomSource, problem, participants,
					fairnessProbability, tournamentSize );
			int expectedIndex = expectedWinners[i];
			Member expected = participants[expectedIndex];
			assertEquals ( "Fight " + i
					+ " did not result in participant at index "
					+ expectedIndex + " winning the fight.", expected, actual );
		}
		// }
	}
}
